package com.easidea.tim.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;



/**
 * 
 * @author gavin.shao
 * 
 */
public final class DateUtil {
	private static DateUtil instance = null;
	private static final String FORMATE_STYLE_DATA_SHORT = "yyyy-MM-dd";
	private static final String FORMATE_STYLE_DATA_LONG = "yyyy-MM-dd HH:ss:mm";
	public static DateUtil getInstance() {
		if (instance == null) {
			instance = new DateUtil();
		}
		return instance;
	}

	private DateUtil() {
	}

	public static Date now() {
		return new Date();
	}
    public static String formatDateTime(Date date){
    	SimpleDateFormat formater = new SimpleDateFormat(FORMATE_STYLE_DATA_LONG);
    	return formater.format(date);
    }
	/**
	 * convert string to date, with default pattern,throws ParseException
	 * 
	 * @param strDate
	 *            the str date
	 * @return date
	 */
	public static Date strToDate(String strDate) {
		return strToDate(strDate, FORMATE_STYLE_DATA_SHORT);
	}

	/**
	 * convert string to date ,with custom pattern,throws
	 * IllegalArgumentException
	 * 
	 * @param strDate
	 *            str
	 * @param format
	 *            format style such as yyyy-MM-dd
	 * @return the date.
	 */
	public static Date strToDate(String strDate, String format) {
		if (strDate == null) {
			return null;
		}

		Date result = null;
		try {
			SimpleDateFormat formater = new SimpleDateFormat(format);
			result = formater.parse(strDate);
		} catch (ParseException e) {
			throw new RuntimeException("String To Date Convert Error", e);
		}
		return result;
	}


	/**
	 * Date to String accroding to the format.
	 * 
	 * @param date
	 *            date
	 * @param format
	 *            format
	 * @return the string format of the data value.
	 */
	public static String dateToStr(Date date, String format) {
		SimpleDateFormat formater = new SimpleDateFormat(format);
		return formater.format(date);
	}
	/**
	 * 由java.util.Date到java.sql.Date的类型转换
	 * @param date
	 * @return Date
	 */
	public static Date getSqlDate(java.util.Date date){
		return new Date(date.getTime());
	}
	
	public static Date nowDate(){
		Calendar calendar=Calendar.getInstance();
		return getSqlDate(calendar.getTime());
	}
	
	/**
	 * 获得某一日期的后一天
	 * @param date
	 * @return Date
	 */
	public static Date getNextDate(Date date){
		Calendar calendar=Calendar.getInstance();
		calendar.setTime(date);
		int day=calendar.get(Calendar.DATE);
		calendar.set(Calendar.DATE,day+1);
		return getSqlDate(calendar.getTime());
	}
	
	/**
	 * 获得某一日期的前一天
	 * @param date
	 * @return Date
	 */
	public static Date getPreviousDate(Date date){
		Calendar calendar=Calendar.getInstance();
		calendar.setTime(date);
		int day=calendar.get(Calendar.DATE);
		calendar.set(Calendar.DATE,day-1);
		return getSqlDate(calendar.getTime());
	}
	
	/**
	 * 获得某年某月第一天的日期
	 * @param year
	 * @param month
	 * @return Date
	 */
	public static Date getFirstDayOfMonth(int year,int month){
		Calendar calendar=Calendar.getInstance();
		calendar.set(Calendar.YEAR,year);
		calendar.set(Calendar.MONTH,month-1);
		calendar.set(Calendar.DATE,1);
		return getSqlDate(calendar.getTime());
	}
	
	/**
	 * 获得某年某月最后一天的日期
	 * @param year
	 * @param month
	 * @return Date
	 */
	public static Date getLastDayOfMonth(int year,int month){
		Calendar calendar=Calendar.getInstance();
		calendar.set(Calendar.YEAR,year);
		calendar.set(Calendar.MONTH,month);
		calendar.set(Calendar.DATE,1);
		return getPreviousDate(getSqlDate(calendar.getTime()));
	}
	
	/**
	 * 由年月日构建java.sql.Date类型
	 * @param year
	 * @param month
	 * @param date
	 * @return Date
	 */
	public static Date buildDate(int year,int month,int date){
		Calendar calendar=Calendar.getInstance();
		calendar.set(year,month-1,date);
		return getSqlDate(calendar.getTime());
	}
	
	/**
	 * 取得某月的天数
	 * @param year
	 * @param month
	 * @return int
	 */
	public static int getDayCountOfMonth(int year,int month){
		Calendar calendar=Calendar.getInstance();
		calendar.set(Calendar.YEAR,year);
		calendar.set(Calendar.MONTH,month);
		calendar.set(Calendar.DATE,0);
		return calendar.get(Calendar.DATE);
	}
	
	/**
	 * 获得某年某季度的最后一天的日期
	 * @param year
	 * @param quarter
	 * @return Date
	 */
	public static Date getLastDayOfQuarter(int year,int quarter){
		int month=0;
		if(quarter>4){
			return null;
		}else{
			month=quarter*3;
		}
		return getLastDayOfMonth(year,month);
		
	}
	
	/**
	 * 获得某年某季度的第一天的日期
	 * @param year
	 * @param quarter
	 * @return Date
	 */
	public static Date getFirstDayOfQuarter(int year,int quarter){
		int month=0;
		if(quarter>4){
			return null;
		}else{
			month=(quarter-1)*3+1;
		}
		return getFirstDayOfMonth(year,month);
	}
	
	/**
	 * 获得某年的第一天的日期
	 * @param year
	 * @return Date
	 */
	public static Date getFirstDayOfYear(int year){
		return getFirstDayOfMonth(year,1);
	}
	
	/**
	 * 获得某年的最后一天的日期
	 * @param year
	 * @return Date
	 */
	public static Date getLastDayOfYear(int year){
		return getLastDayOfMonth(year,12);
	}

	/**
	 * 获得给定时间的00:00:00
	 * 
	 * @param date
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Date getStartTime(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(dealwithDateNull(date));

		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		Date startTime = calendar.getTime();
		// startTime.setHours(0);
		// startTime.setMinutes(0);
		// startTime.setSeconds(0);
		return startTime;
	}

	/**
	 * 获得给定时间的23:59:59
	 * 
	 * @param date
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Date getEndTime(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(dealwithDateNull(date));

		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		Date startTime = calendar.getTime();
		// startTime.setHours(23);
		// startTime.setMinutes(59);
		// startTime.setSeconds(59);
		return startTime;
	}

	/**
	 * Deal with the date -- if the date is null then return the current time
	 * otherwise return itself.
	 * 
	 * @param date
	 *            date
	 * @return date
	 */
	public static Date dealwithDateNull(Date date) {
		if (date == null) {
			return new Date();
		}
		return date;
	}

	// add by alex.su@2008-6-4
	/**
	 * GMT+8 timzone offset value.
	 */
	public static final String CST_TIMEZONE_OFFSET = "-480";

	/**
	 * Convert the date to GMT.
	 * 
	 * @param date
	 *            date.
	 * @return GMT Date.
	 */
	public static Date toGMTDate(Date date, String timeZoneDigital) {
		if (date == null) {
			return null;
		}

		Calendar cal = Calendar.getInstance(getTimeZone(timeZoneDigital));
		cal.setTime(date);

		cal.add(Calendar.HOUR_OF_DAY, getTimeOffSet(timeZoneDigital));
		// add at 20071015 by Jeecy for the timezone maybe infact minute.
		cal.add(Calendar.MINUTE, getMinuteOffSet(timeZoneDigital));
		return cal.getTime();
	}

	/**
	 * Convert the date to GMT.
	 * 
	 * @param strDate
	 *            strDate.
	 * @return GMT Date.
	 */
	public static Date toGMTDate(String strDate, String timeZoneDigital) {
		Date date = strToDate(strDate);
		Calendar cal = Calendar.getInstance(getTimeZone(timeZoneDigital));
		cal.setTime(date);

		cal.add(Calendar.HOUR_OF_DAY, getTimeOffSet(timeZoneDigital));
		// add at 20071015 by Jeecy for the timezone maybe infact minute.
		cal.add(Calendar.MINUTE, getMinuteOffSet(timeZoneDigital));
		return cal.getTime();
	}

	/**
	 * Convert date to the special timezone date.<br>
	 * If timeZoneDigital==null, default convert to GMT+8(CST).
	 * 
	 * @param date
	 *            date
	 * @param timeZoneDigital
	 *            timeZoneDigital
	 * @return the special timezone date.
	 */
	public static Date toLocalDate(Date date, String timeZoneDigital) {
		Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
		cal.setTime(date);
		cal.add(Calendar.HOUR_OF_DAY, -getTimeOffSet(timeZoneDigital));
		// add at 20071015 by Jeecy for the timezone maybe infact minute.
		cal.add(Calendar.MINUTE, -getMinuteOffSet(timeZoneDigital));
		return cal.getTime();
	}

	/**
	 * Get the timezone according to the timeZone_digital. <br>
	 * If the timeZoneDigital==null, default return GMT+8(CST).
	 * 
	 * @param timeZoneDigital
	 * @return
	 */
	public static TimeZone getTimeZone(String timeZoneDigital) {
		String gmt = "";
		if (timeZoneDigital != null) {
			int length = timeZoneDigital.length();
			String f = "";
			if (length == 1) {
				gmt = "GMT";
			} else if (timeZoneDigital.startsWith("-")) {
				f = timeZoneDigital.substring(1, length);
				gmt = "GMT+" + Integer.parseInt(f) / 60;
			} else {
				gmt = "GMT-" + Integer.parseInt(timeZoneDigital) / 60;
			}

		} else {
			return TimeZone.getTimeZone("GMT+8");
		}
		return TimeZone.getTimeZone(gmt);
	}

	private static int getTimeOffSet(String timeZoneDigital) {
		String localTimeZone = CST_TIMEZONE_OFFSET;
		if (timeZoneDigital != null && timeZoneDigital.trim().length() > 0) {
			localTimeZone = timeZoneDigital;
		}
		return Integer.parseInt(localTimeZone) / 60;
	}

	private static int getMinuteOffSet(String timeZoneDigital) {
		String localTimeZone = CST_TIMEZONE_OFFSET;
		if (timeZoneDigital != null && timeZoneDigital.trim().length() > 0) {
			localTimeZone = timeZoneDigital;
		}
		return (Integer.parseInt(localTimeZone) % 60);
	}

}
